package com.znyj.cloud.chain.server;

import com.znyj.cloud.chain.tcphandler.TcpServerInitializer;
import com.znyj.cloud.device.constant.SysConstant;
import com.znyj.cloud.device.util.LocalInfoUtil;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * Created by gaoliwei on 15-1-13.
 */
@Component
public class TCPServer implements Runnable {

    @Resource
    private TcpServerInitializer tcpServerInitializer;

    public void init() {
        int PORT = SysConstant.PORT;

        EventLoopGroup bossGroup = new NioEventLoopGroup(); //acceptor thread pool
        EventLoopGroup workerGroup = new NioEventLoopGroup(8);//IO thread pool

        try {
            ServerBootstrap b = new ServerBootstrap();//启动NIO服务的辅助启动类
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)//指定接收连接的Channel的类
                    .childHandler(tcpServerInitializer)//指定pipeLine
                    //.option(ChannelOption.SO_RCVBUF, 1024 * 1024)
                    //.option(ChannelOption.TCP_NODELAY, true);//关闭延迟发送
                    .option(ChannelOption.SO_KEEPALIVE, true) //维持连接的活跃,清除死连接
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .option(ChannelOption.SO_REUSEADDR, true)
                    .option(ChannelOption.TCP_NODELAY, true);

            Channel ch = b.bind(PORT).sync().channel();//绑定端口
            System.out.println("tcp server start at " + LocalInfoUtil.getIP() + ":" + PORT);
            ch.closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    @Override
    public void run() {
        init();
    }
}
